using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class PlayerController : MonoBehaviour
{
    [Header("获取组件")]
    private Rigidbody2D rb;
    private Animator anim;
    private CapsuleCollider2D coll;
    //public Collider2D DisColl;
    [Header("设置声音")]
    //public AudioSource jumpAudio, hurtAudio, collectionAudio, deadAudio;
    [Header("移动参数")]
    public float speed;
    public float jumpForce;
    [SerializeField] private float horizontalMove;
    [SerializeField] private float faceDirection;
    [SerializeField] private bool jumpPressed, crouchPressed;
    public int jumpState;
    [Header("对象池组件")]
    public GameObject shadowPool;
    [Header("CD的UI组件")]
    public Image cdImage;
    [Header("Dash参数")]
    public float dashTime;//dash时长
    private float dashTimeLeft;//冲锋剩余时间
    private float lastDash = -10f;//上一次冲锋的时间
    public float dashCoolDown;
    public float dashSpeed;
    public bool isDashing;
    [Header("积分及道具")]
    public int score;
    public int cherry;
    public int gem;
    public Text scoreNumber;
    public Text cherryNumber;
    public Text gemNumber;
    [Header("环境检测")]
    public LayerMask ground;
    public LayerMask Ladder;
    public LayerMask enemyCheck;
    public Transform groundCheck;
    public Transform headCheck;
    public float groundDistance = 0.3f;
    public bool isGround;
    [Header("人物状态")]
    private bool isHurt;
    public bool isHeadBlocked;
    private float hurtTime;
    [Header("碰撞体尺寸")]
    private Vector2 normalSize, normalOffset;
    private Vector2 crouchSize, crouchOffset;
    [Header("获取特殊敌人游戏物体")]
    public GameObject oppssum;
    public GameObject eagle;
    [Header("获取隐藏地图")]
    public Collider2D hideMap;
    [Header("获取场景中地图参数")]
    public Rigidbody2D mapRb, hideMapRb, door, ladder;
    public GameObject environment;
    //相机抖动
    private Cinemachine.CinemachineCollisionImpulseSource MyInpulse;
    //计时变量
    private int shakeTime = 1200;
    //危险提示
    public GameObject signForDanger;
    [Header("爬梯相关参数")]
    public float climbSpeed;
    private bool isLadder;
    private bool isClimbing;
    private bool isJumping;
    private bool isFalling;
    private bool isStoping;
    private bool isCrouching;
    [Header("UIManager")]
    private int deathCount;
    private int timeCount;

    //所要到的平台的碰撞体
    public Collider2D platform;
    //初始的重力
    private float playerGravity;
    [Header("陷阱")]
    public GameObject hutao;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        coll = GetComponent<CapsuleCollider2D>();
        MyInpulse = GetComponent<Cinemachine.CinemachineCollisionImpulseSource>();
        playerGravity = rb.gravityScale;

        normalSize = coll.size;
        normalOffset = coll.offset;
        crouchSize = new Vector2(coll.size.x, coll.size.y / 2.0f);
        crouchOffset = new Vector2(coll.offset.x, coll.offset.y - 0.2f);
    }

    void FixedUpdate()
    {
        isGround = Physics2D.OverlapCircle(groundCheck.position, 0.1f, ground);

        PhysicsCheck();
        if (!isHurt)
        {
            Movement();
            Jump();
            Dash();
            if (isDashing)
                return;
        }

        switchAnim();
        //CameraShake();
        HideMapControl();

        //UIManager.UpdateDeath(deathCount);
    }
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.J) && shadowPool.activeInHierarchy)
        {
            if (Time.time >= (lastDash + dashCoolDown))
            {
                //可以执行dash
                ReadyToDash();
            }
        }
        if (Input.GetButtonDown("Jump"))
        {
            jumpPressed = true;
        }

        if (Input.GetButtonDown("Crouch"))
        {
            crouchPressed = true;
        }
        else if (Input.GetButtonUp("Crouch"))
        {
            crouchPressed = false;
        }

        //攀爬
        CheckLadder();
        Climb();
        CheckAirStatus();

        cdImage.fillAmount -= 1.0f / dashCoolDown * Time.deltaTime;
    }

    //检测梯子
    void CheckLadder()
    {
        isLadder = coll.IsTouchingLayers(Ladder);
    }

    void Climb()
    {
        if (isLadder)
        {

            anim.SetBool("jumping", false);
            platform.enabled = false;
            //Physics2D.IgnoreCollision(coll, platform, true);
            //Physics2D.IgnoreCollision(coll.GetComponents<Collider2D>()[1], platform);
            float verticalMove = Input.GetAxis("Vertical");
            if (verticalMove > 0.3f || verticalMove < -0.3f)
            {
                anim.SetBool("climbing", true);
                rb.gravityScale = 0;
                rb.velocity = new Vector2(rb.velocity.x, verticalMove * climbSpeed);
            }
            else
            {

                anim.SetBool("climbing", false);
                anim.SetBool("stoping", true);
                rb.velocity = new Vector2(rb.velocity.x, 0.0f);
            }
        }
        else
        {
            platform.enabled = true;
            //Physics2D.IgnoreCollision(coll, platform, false);
            anim.SetBool("climbing", false);
            anim.SetBool("stoping", false);
            rb.gravityScale = playerGravity;

        }


    }

    void CheckAirStatus()
    {
        isJumping = anim.GetBool("jumping");
        isFalling = anim.GetBool("falling");
        isClimbing = anim.GetBool("climbing");
        isStoping = anim.GetBool("stoping");
        isCrouching = anim.GetBool("crouching");
    }

    //射线检测
    void PhysicsCheck()
    {
        RaycastHit2D headCheck = Raycast(new Vector2(0f, -0.1f), Vector2.up, groundDistance, ground);
        if (headCheck)
            isHeadBlocked = true;
        else isHeadBlocked = false;
    }

    RaycastHit2D Raycast(Vector2 offset, Vector2 rayDirection, float length, LayerMask layer)
    {
        Vector2 pos = transform.position;

        RaycastHit2D hit = Physics2D.Raycast(pos + offset, rayDirection, length, layer);

        Color color = hit ? Color.red : Color.green;

        Debug.DrawRay(pos + offset, rayDirection * length, color);

        return hit;
    }

    void Movement()
    {
        horizontalMove = Input.GetAxisRaw("Horizontal");
        faceDirection = Input.GetAxisRaw("Horizontal");


        rb.velocity = new Vector2(horizontalMove * speed, rb.velocity.y);
        anim.SetFloat("running", Mathf.Abs(faceDirection));

        if (faceDirection != 0)
        {
            rb.transform.localScale = new Vector3(faceDirection, 1, 1);
        }

        Crouch();
    }
    void Jump()
    {
        if (jumpPressed && jumpState > 0)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            anim.SetBool("jumping", true);
            anim.SetBool("hurt", false);
            SoundManager.instance.JumpAudio();
            //jumpAudio.Play();
            jumpPressed = false;
            jumpState--;
        }
    }

    void Crouch()
    {
        if (crouchPressed && isClimbing == false && isStoping == false)
        {
            anim.SetBool("crouching", true);
            //DisColl.enabled = false;
            coll.size = crouchSize;
            coll.offset = crouchOffset;
        }
        else if (!crouchPressed && !isHeadBlocked)
        {
            anim.SetBool("crouching", false);
            //DisColl.enabled = true;
            coll.size = normalSize;
            coll.offset = normalOffset;
        }
    }

    void Restart()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    //切换动画
    void switchAnim()
    {
        if (rb.velocity.y < 0.1f && !coll.IsTouchingLayers(ground))
        {
            anim.SetBool("falling", true);
        }
        if (anim.GetBool("jumping"))
        {
            if (rb.velocity.y < 0)
            {
                anim.SetBool("jumping", false);
                anim.SetBool("falling", true);
            }
        }
        else if (isHurt)
        {
            hurtTime += Time.deltaTime;
            anim.SetBool("hurt", true);
            rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y);
            if (hurtTime > 1.0)
            {
                anim.SetBool("hurt", false);
                isHurt = false;
                hurtTime = 0;
            }
        }
        else if (isGround)
        {
            anim.SetBool("falling", false);
            jumpState = 2;
        }

        //爬梯
    }

    void HideMapControl()
    {
        if (cherry == 22)
        {
            hideMap.enabled = true;
        }
        CameraShake();
    }

    void CameraShake()
    {
        if (cherry == 22 && shakeTime > 0)
        {
            MyInpulse.GenerateImpulse();
            shakeTime--;
            signForDanger.SetActive(true);
        }
        else if (shakeTime == 0)
        {
            environment.SetActive(false);
            mapRb.bodyType = RigidbodyType2D.Dynamic;
            hideMapRb.bodyType = RigidbodyType2D.Dynamic;
            door.bodyType = RigidbodyType2D.Dynamic;
            //ladder.bodyType = RigidbodyType2D.Dynamic;
        }
    }

    //收集物品
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Collections")
        {
            //collectionAudio.Play();
            SoundManager.instance.CherryAudio();
            other.GetComponent<Animator>().Play("isGot");
            //Destroy(other.gameObject);
            cherry++;
            score++;
            scoreNumber.text = score.ToString();
            cherryNumber.text = cherry.ToString();
        }
        else if (other.tag == "Collections_sup")
        {
            //collectionAudio.Play();
            SoundManager.instance.CherryAudio();
            other.GetComponent<Animator>().Play("isGot");
            //Destroy(other.gameObject);
            gem++;
            score += 4;
            scoreNumber.text = score.ToString();
            gemNumber.text = gem.ToString();
        }
        else if (other.tag == "DeadCherry")
        {
            SoundManager.instance.CherryAudio();
            other.GetComponent<Animator>().Play("isGot");
            hutao.SetActive(true);
        }
        else if (other.tag == "Dead")
        {
            //GetComponent<AudioSource>().enabled = false;//只对第一个AudioSource起作用
            // Destroy(this.gameObject);//直接摧毁会导致人物所挂载的脚本也无法使用
            SoundManager.instance.DeadAudio();
            GameManager.PlayerDied();
            anim.SetTrigger("dead");

            rb.gravityScale = 0;
            rb.simulated = false;
            speed = 0;
            //deathCount++;

            //Invoke("Restart", 4f);
        }
        else if (other.tag == "HideEntrance")
        {
            transform.position = new Vector3(97.2f, 11.51f, -1.36f);
        }
        else if (other.tag == "Trap")
        {
            oppssum.SetActive(true);
        }
        else if (other.tag == "Trap_2")
        {
            eagle.SetActive(true);
        }
    }

    //消灭敌人
    private void OnCollisionEnter2D(Collision2D collision)
    {
        //int distance;
        DestroiableWall wall = collision.gameObject.GetComponent<DestroiableWall>();
        if (collision.gameObject.tag == "Enemy")
        {
            //Enemy_Frog frog = collision.gameObject.GetComponent<Enemy_Frog>();
            //Enemy_Eagle eagle = collision.gameObject.GetComponent<Enemy_Eagle>();//无法判断碰撞物体是哪个
            Enemy enemy = collision.gameObject.GetComponent<Enemy>();
            if (Physics2D.OverlapCircle(groundCheck.position, 0.4f, enemyCheck))
            {
                enemy.JumpOn();
                //eagle.JumpOn();
                //Destroy(collision.gameObject);
                rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            }
            //受伤后反弹
            else
            {
                //distance = Mathf.FloorToInt(transform.position.x - collision.gameObject.transform.position.x);
                rb.velocity = new Vector2(transform.position.x - collision.gameObject.transform.position.x > 0 ? 10 : -10, rb.velocity.y);
                isHurt = true;
                //hurtAudio.Play();
                SoundManager.instance.HurtAudio();
            }

        }
        //破坏墙体
        if (collision.gameObject.tag == "Wall" && isDashing)
        {
            wall.DashOn();
        }
    }

    void ReadyToDash()
    {
        isDashing = true;
        dashTimeLeft = dashTime;
        lastDash = Time.time;

        cdImage.fillAmount = 1;
    }

    void Dash()
    {
        if (isDashing)
        {
            if (dashTimeLeft > 0)
            {
                if (rb.velocity.y > 0 && !coll.IsTouchingLayers(ground))
                {
                    rb.velocity = new Vector2(dashSpeed * transform.localScale.x, jumpForce);
                }

                rb.velocity = new Vector2(dashSpeed * transform.localScale.x, rb.velocity.y);

                dashTimeLeft -= Time.deltaTime;

                ShadowPool.instance.GetFromPool();
            }
            if (dashTimeLeft <= 0)
            {
                isDashing = false;
                if (!coll.IsTouchingLayers(ground))
                {
                    rb.velocity = new Vector2(dashSpeed * transform.localScale.x, jumpForce);
                }
            }
        }
    }
}
